package com.duckclouddrive.controller;


import com.duckclouddrive.entity.constants.Constants;
import com.duckclouddrive.entity.dto.SessionShareDto;
import com.duckclouddrive.entity.dto.SessionWebUserDto;
import com.duckclouddrive.entity.enums.ResponseCodeEnum;
import com.duckclouddrive.entity.vo.PaginationResultVO;
import com.duckclouddrive.entity.vo.ResponseVO;
import com.duckclouddrive.utils.CopyTools;
import com.duckclouddrive.utils.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;


public class ABaseController {

    private static final Logger logger = LoggerFactory.getLogger(ABaseController.class);

    protected static final String STATUC_SUCCESS = "success";

    protected static final String STATUC_ERROR = "error";

    protected <T> ResponseVO getSuccessResponseVO(T t) {
        ResponseVO<T> responseVO = new ResponseVO<>();
        responseVO.setStatus(STATUC_SUCCESS);
        responseVO.setCode(ResponseCodeEnum.CODE_200.getCode());
        responseVO.setInfo(ResponseCodeEnum.CODE_200.getMsg());
        responseVO.setData(t);
        return responseVO;
    }

    /**
     * 将一种类型的分页结果转换为另一种类型的分页结果
     *
     * @param <S> 源类型
     * @param <T> 目标类型
     * @param result 原始的分页结果
     * @param classz 目标类型类
     * @return 转换后的分页结果
     */
    protected <S, T> PaginationResultVO<T> convert2PaginationVO(PaginationResultVO<S> result, Class<T> classz) {
        // 创建一个新的分页结果对象
        PaginationResultVO<T> resultVO = new PaginationResultVO<>();
        // 将源列表转换为目标列表
        resultVO.setList(CopyTools.copyList(result.getList(), classz));
        // 复制页码
        resultVO.setPageNo(result.getPageNo());
        // 复制页大小
        resultVO.setPageSize(result.getPageSize());
        // 复制总页数
        resultVO.setPageTotal(result.getPageTotal());
        // 复制总记录数
        resultVO.setTotalCount(result.getTotalCount());
        // 返回转换后的分页结果
        return resultVO;
    }

    /**
     * 从HTTP会话中获取用户信息
     *
     * 此方法用于从给定的HTTP会话中提取用户信息对象它尝试从会话属性中获取一个名为
     * Constants.SESSION_KEY 的属性，该属性应包含一个 SessionWebUserDto 对象如果会话中不存在该属性，
     * 则返回 null
     *
     * @param session HTTP会话对象，从中获取用户信息
     * @return SessionWebUserDto 返回包含用户信息的对象，如果会话中不存在用户信息，则返回 null
     */
    protected SessionWebUserDto getUserInfoFromSession(HttpSession session) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) session.getAttribute(Constants.SESSION_KEY);
        return sessionWebUserDto;
    }

    protected SessionShareDto getSessionShareFromSession(HttpSession session, String shareId) {
        SessionShareDto sessionShareDto = (SessionShareDto) session.getAttribute(Constants.SESSION_SHARE_KEY + shareId);
        return sessionShareDto;
    }


    /**
     * 读取服务器上的文件，并将其内容输出到浏览器
     *
     * @param response 用于获取输出流，通过它将文件内容输出到浏览器
     * @param filePath 待读取文件的路径
     */
    protected void readFile(HttpServletResponse response, String filePath) {
        // 检查文件路径是否安全，防止目录遍历攻击
        if (!StringTools.pathIsOk(filePath)) {
            return;
        }
        OutputStream out = null;
        FileInputStream in = null;
        try {
            // 创建文件对象
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                return;
            }
            // 创建文件输入流
            in = new FileInputStream(file);
            // 定义一个缓冲区用于存储读取的文件数据
            byte[] byteData = new byte[1024];
            // 获取输出流，用于将数据输出到浏览器
            out = response.getOutputStream();
            // 读取文件数据到缓冲区，返回实际读取的字节数，当返回-1时表示读取完毕
            int len = 0;
            while ((len = in.read(byteData)) != -1) {
                // 将缓冲区的数据输出到浏览器
                out.write(byteData, 0, len);
            }
            // 刷新输出流，确保所有数据都被正确输出
            out.flush();
        } catch (Exception e) {
            // 记录读取文件过程中的异常信息
            logger.error("读取文件异常", e);
        } finally {
            // 关闭输出流
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // 记录关闭输出流时发生的IO异常信息
                    logger.error("IO异常", e);
                }
            }
            // 关闭输入流
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // 记录关闭输入流时发生的IO异常信息
                    logger.error("IO异常", e);
                }
            }
        }
    }
}
